import { Value } from "./Value";
import { Saturation } from "./Saturation";
import { changeColor, toRGBAString } from "./utils";
import { Hue } from "./Hue";
import { Alpha } from "./Alpha";
import { Recommend } from "./Recommend";
import { PropType, computed, defineComponent, ref, watchEffect } from "vue";
import createField from "../../use/createField";
import Dropdown from "../../Dropdown";
import Space from "../../Space";
import Input from "../Input";
import Button from "../../Button";

interface ColorPickerProps {
    name?: string
    modelValue?: string
    transfer?: boolean
    inline?: boolean
    align?: 'bottomLeft'|'bottomRight'
    disabled?: boolean
    alpha?: boolean
    size?: 'small'|'large'
    recommend?: boolean
    colors?: string[]
    asFormField?: boolean
}

export default defineComponent({
    name: 'ColorPicker',
    props: {
        name: {type: String as PropType<ColorPickerProps['name']>, default: ''},
        modelValue: {type: String as PropType<ColorPickerProps['modelValue']>, default: ''},
        transfer: {type: Boolean as PropType<ColorPickerProps['transfer']>, default: false},
        inline: {type: Boolean as PropType<ColorPickerProps['inline']>, default: false},
        align: {type: String as PropType<ColorPickerProps['align']>, default: 'bottomLeft'},
        disabled: {type: Boolean as PropType<ColorPickerProps['disabled']>, default: false},
        alpha: {type: Boolean as PropType<ColorPickerProps['alpha']>, default: false},
        size: {type: String as PropType<ColorPickerProps['size']>, default: ''},
        recommend: {type: Boolean as PropType<ColorPickerProps['recommend']>, default: false},
        colors: {type: Array as PropType<ColorPickerProps['colors']>},
        asFormField: {type: Boolean as PropType<ColorPickerProps['asFormField']>, default: true},
    },
    emits: ['change', 'update:modelValue'],
    setup (props, {emit}) {
        const open = ref(false);
        const align = props.align ?? 'bottomLeft';
        const value = createField(props, emit, '');
        const val = ref(changeColor(value.value || '#2D8CF0'));
        const confirmVal = ref('');

        let oldHue: any = val.value;
        const classList = computed(() => ({
            'cm-color-picker': true,
            [`cm-color-picker-${props.size}`]: props.size,
            'cm-color-picker-disabled': props.disabled,
        }));

        const inlineClassList = computed(() => ({
            'cm-color-picker-wrap': true,
            'cm-color-picker-inline': props.inline,
            'cm-color-picker-disabled': props.disabled,
        }));

        const onColorChange = (data: any) => {
            colorChange(data);
        };

        const colorChange = (data: any, _oldHue?: any) => {
            oldHue = val.value.hsl.h;
            val.value = changeColor(data, _oldHue || oldHue);
        };

        const onConfirm = () => {
            open.value = false;
            value.value = confirmVal.value;
            emit('change', confirmVal.value);
        };

        const onClear = () => {
            open.value = false;
            value.value = '';
            emit('change', '');
        };

        watchEffect(() => {
            if (props.alpha) {
                confirmVal.value = toRGBAString(val.value.rgba);
            } else {
                confirmVal.value = val.value.hex;
            }
        });

        watchEffect(() => {
            const v = changeColor(confirmVal.value);
            val.value = v;
        });

        const renderMain = () => {
            return <Space dir="v">
                <Saturation value={val.value} onChange={onColorChange}/>
                <Hue value={val.value} onChange={onColorChange}/>
                { props.alpha && <Alpha value={val.value} onChange={onColorChange}/> }
                { props.recommend && <Recommend colors={props.colors} onChange={onColorChange}/> }
                <div class="cm-color-picker-confirm">
                    <Space dir="h">
                        <Input size="small" class="cm-color-picker-input" v-model={confirmVal.value}/>
                        <Button size="small" type="default" onClick={onClear}>清除</Button>
                        <Button size="small" type="primary" onClick={onConfirm}>确定</Button>
                    </Space>
                </div>
            </Space>;
        };

        return () => props.inline ? <div class={inlineClassList.value}>
            {renderMain()}
        </div>
            : <div class={classList.value}>
                <Dropdown transfer={props.transfer} align={align} disabled={props.disabled} trigger="click" v-model={open.value}
                    menu={<div class="cm-color-picker-wrap">
                        {renderMain()}
                    </div>}>
                    <Value disabled={props.disabled} currentValue={val.value} value={value.value} open={open.value}/>
                </Dropdown>
            </div>;
    }
});
